package ui

import (
	"fmt"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/widget"
	"image/color"
	"log"
	"ping-info-go/internal/ping"
	"ping-info-go/internal/store"
	"ping-info-go/pkg/global"
	"time"
)

func MakeNotice(_ fyne.Window) fyne.CanvasObject {
	return widget.NewRichTextFromMarkdown(
		"## 欢迎使用成都地铁网络测试系统\n\n" +
			"- 本系统用于测试成都地铁内部网络的延迟和丢包率。\n" +
			"- 因为操作系统限制需要以管理员身份运行。\n" +
			"- 在`config.csv`文件中配置要测试的站点。\n" +
			"- 在`config.ini`文件中配置运行参数。\n" +
			"- 点击左上角`开始`按钮开始测试。\n" +
			"- 开始之后点击左上角`重启`按钮将清空测试结果重新开始测试。\n" +
			"- 测试结果将在下方表格中显示。\n" +
			"- 右上角可以导出测试结果。",
	)
}

func MakeLayout(w fyne.Window) fyne.CanvasObject {
	top := makeTopBar(w)
	table := makeTable(w)
	return container.New(
		layout.NewBorderLayout(top, nil, nil, nil),
		table,
		top,
	)
}

// makeTopBar 顶部控件 OBJ
func makeTopBar(w fyne.Window) fyne.CanvasObject {

	buttonStartChan := make(chan bool, 1)
	buttonReversalChan := make(chan bool, 1)

	buttonStart := widget.NewButton(
		"开始",
		func() {
			buttonStartChan <- true
			buttonReversalChan <- true
			log.Println("开始")
			ping.RunPing(true)
			buttonStartChan <- false
		},
	)

	buttonReversal := widget.NewButton(
		"暂停",
		func() {
			buttonReversalChan <- true
			store.PingStatus.ReversalPing()
		},
	)
	buttonReversal.Disable()

	buttonExport := widget.NewButton(
		"导出",
		func() {
			// 1. 生成系统默认文件名（含时间戳，确保唯一性）
			timestamp := time.Now().Format("20060102150405")               // 格式：YYYYMMDDHHMMSS
			defaultFilename := fmt.Sprintf("ping_info_%s.xlsx", timestamp) // 自动填入 .xlsx 扩展名

			// 2. 创建文件保存对话框并设置默认文件名
			saveDialog := dialog.NewFileSave(
				func(writer fyne.URIWriteCloser, err error) {
					if err != nil {
						dialog.ShowError(err, w)
						return
					}
					if writer == nil {
						return
					}

					defer func(writer fyne.URIWriteCloser) {
						_ = writer.Close()
					}(writer)

					excel, err := store.GenerateExcel(store.TableDataList)
					if err != nil {
						dialog.ShowError(err, w)
						return
					}

					// 5. 将 Excel 内容写入文件
					if err = excel.Write(writer); err != nil {
						dialog.ShowError(fmt.Errorf("写入Excel失败: %v", err), w)
						return
					}

					dialog.ShowInformation("成功", "Excel文件已导出", w)
				}, w)

			// 设置默认文件名（关键：自动填入文件名和扩展名）
			saveDialog.SetFileName(defaultFilename)
			saveDialog.Show() // 显示对话框
		},
	)

	go func() {
		for {
			select {
			case <-buttonReversalChan:
				reversalButtonName := "暂停"
				if store.PingStatus.Paused {
					reversalButtonName = "继续"
				}
				fyne.Do(func() {
					buttonReversal.SetText(reversalButtonName)
				})
			case buttonStartStatus := <-buttonStartChan:
				fyne.Do(func() {
					if buttonStartStatus {
						buttonStart.Disable()
					} else {
						buttonStart.Enable()
					}

					buttonStart.SetText("重启")
					buttonReversal.Enable()
				})
			}
		}
	}()

	// 使用 HBox 水平排列按钮
	return container.NewHBox(
		buttonStart,
		//buttonReversal,
		layout.NewSpacer(),
		widget.NewLabelWithData(store.MiddleInfoBind),
		buttonExport,
	)
}

// makeTable 表格 OBJ
func makeTable(_ fyne.Window) *widget.Table {
	t := widget.NewTableWithHeaders(
		func() (int, int) { return len(global.Services), len(global.HeaderConf) },
		// 1. 创建单元格：Label + 背景层（canvas.Rectangle）
		func() fyne.CanvasObject {
			// 创建背景矩形（用于设置背景色）
			bg := canvas.NewRectangle(color.Transparent)
			// 创建文本标签
			label := widget.NewLabel("")
			label.TextStyle.Bold = true
			// 组合：背景矩形 + 标签（使用 Max 容器让背景充满单元格）
			return container.NewStack(bg, label)
		},
		// 2. 更新单元格内容和背景色
		func(id widget.TableCellID, cell fyne.CanvasObject) {
			// 解析容器内的背景矩形和标签
			c := cell.(*fyne.Container)
			bg := c.Objects[0].(*canvas.Rectangle) // 背景层
			label := c.Objects[1].(*widget.Label)  // 文本层

			if id.Row >= len(store.TableDataList) {
				label.SetText("")
				bg.FillColor = color.Transparent // 空行透明背景
				return
			}

			rowData := store.TableDataList[id.Row]
			label.SetText(rowData.GetShowStr(id.Col))
			bg.FillColor = rowData.GetShowColor()
			bg.Refresh() // 刷新背景色（关键：通知UI更新）
		},
	)

	// 设置表头内容
	t.UpdateHeader = func(id widget.TableCellID, cell fyne.CanvasObject) {
		label := cell.(*widget.Label)

		label.TextStyle = fyne.TextStyle{Bold: true} // 表头加粗
		col := id.Col

		// 第一列序号
		if col < 0 {
			label.SetText(fmt.Sprintf("%d", id.Row+1))
			return
		}

		label.SetText(global.HeaderConf[col].Name)
	}

	// 设置Header高度
	t.SetRowHeight(-1, 40)
	for col, conf := range global.HeaderConf {
		if conf.Length > 0 {
			t.SetColumnWidth(col, conf.Length)
		}
	}

	// 定时更新数据
	go func() {
		for range time.Tick(time.Second) {
			// 刷新表格数据
			fyne.Do(func() {
				t.Refresh()
			})

			middleInfoStr := "当前运行中"
			if store.PingStatus.Paused {
				middleInfoStr = "当前暂停中"
				if store.PingStatus.Started {
					middleInfoStr = "下次运行时间:" + store.TimePingNext.Format("2006-01-02 15:04:05") + " " + middleInfoStr
				}
			}
			_ = store.MiddleInfoBind.Set(middleInfoStr)
		}
	}()

	return t
}
